
package org.ricks.ioc.definition;

import org.ricks.ioc.BeanAnalysisProcessor;
import org.ricks.ioc.HotfixManager;
import org.ricks.ioc.LifeCycleMethod;
import org.ricks.ioc.RicksContext;
import org.ricks.ioc.anno.*;
import org.ricks.ioc.definition.filed.FieldDefinition;
import org.ricks.ioc.definition.filed.DefaultFieldDefinition;
import org.ricks.ioc.definition.filed.ValueFieldDefinition;
import org.ricks.ioc.utils.ClassUtils;
import org.ricks.ioc.utils.Logger;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 默认的Bean定义描述类.
 * 准备反射使用
 */
public class DefaultBeanDefinition implements BeanDefinition {

    /**
     * 缓存那个单例对象
     */
    protected final Object bean;

    private final Class<?> beanClass;

    private Annotation annotation;

    private Class<? extends Annotation> annotationType;
    

    /**
     * 所有需要注入的属性
     */
    private final ArrayList<FieldDefinition> autowiredFields = new ArrayList<>();

    public DefaultBeanDefinition(Object bean) {
        this(bean.getClass(), bean);
        if(bean instanceof BeanAnalysisProcessor beanAnalysisProcessor) {
            RicksContext.me().addBeanAnalysisProcessor(beanAnalysisProcessor);
        }
        Method[] methods = bean.getClass().getDeclaredMethods();
        for (Method method: methods) {
            Init init = method.getAnnotation(Init.class);
            if(Objects.nonNull(init)) RicksContext.me().addLifeCycleMethod(Init.class, new LifeCycleMethod(bean, method , init.priority()));
            PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
            if(Objects.nonNull(preDestroy)) RicksContext.me().addLifeCycleMethod(PreDestroy.class, new LifeCycleMethod(bean, method
                    , preDestroy.priority()));
        }
    }

    public DefaultBeanDefinition(Class<?> klass) {
        this(klass, ClassUtils.newInstance(klass));
        if(bean instanceof BeanAnalysisProcessor beanAnalysisProcessor) {
            RicksContext.me().addBeanAnalysisProcessor(beanAnalysisProcessor);
        }
        Method[] methods = klass.getDeclaredMethods();
        for (Method method: methods) {
            Init init = method.getAnnotation(Init.class);
            if(Objects.nonNull(init)) RicksContext.me().addLifeCycleMethod(Init.class, new LifeCycleMethod(bean, method , init.priority()));
            PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
            if(Objects.nonNull(preDestroy)) RicksContext.me().addLifeCycleMethod(PreDestroy.class, new LifeCycleMethod(bean, method
                    , preDestroy.priority()));
        }
    }


    private DefaultBeanDefinition(Class<?> klass, Object object) {
        this.bean = object;
        this.beanClass = klass;
        this.analysisField();
    }



//    /**
//     * 获取这个Bean的单例缓存对象.
//     *
//     * @return 实例对象.
//     */
//    public Object getBean() {
//        return bean;
//    }

    /**
     * 获取当前Bean的Class
     *
     * @return 当前Bean的Class
     */
    public Class<?> getBeanClass() {
        return beanClass;
    }


    private void analysisField() {
        List<Field> fieldList = new ArrayList<>();
        Class<?> tempClass = beanClass;
        while (tempClass != null) {
            fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
            tempClass = tempClass.getSuperclass();
        }
        fieldList.stream().filter(v -> v.isAnnotationPresent(Autowired.class) || v.isAnnotationPresent(Value.class)).forEach(this::analysisAutowiredOrValue);
    }

    /**
     * 分析注入的类型
     */
    private void analysisAutowiredOrValue(Field field) {
        Value value = field.getAnnotation(Value.class);
        if (value == null) {
            Autowired autowired = field.getAnnotation(Autowired.class);
            // 其他就当普通Bean处理...
            autowiredFields.add(new DefaultFieldDefinition(field, autowired.value()));
        } else {
            autowiredFields.add(new ValueFieldDefinition(field, value.value())); // @Value注入配置属性.
        }
    }

    @Override
    public void injection() {
        this.autowiredFields.forEach((v) -> v.injection(bean));
    }



    /**
     * 获取实际使用的类（优先使用热更后的类）
     */
    private Class<?> getActualClass() {
        Class<?> hotfixClass = HotfixManager.getHotfixClass(beanClass.getName());
        return hotfixClass != null ? hotfixClass : beanClass;
    }

    /**
     * 获取实际使用的Bean实例（优先使用热更后的类实例）
     */
    public Object getBean() {
        Class<?> actualClass = getActualClass();
        if (actualClass != beanClass) {
            // 需要创建热更后的类实例
            try {
                Object hotfixBean = actualClass.getConstructor().newInstance();
                // 复制字段值
                copyFieldValues(bean, hotfixBean);
                return hotfixBean;
            } catch (Exception e) {
                Logger.error("创建热更实例失败", e);
                return bean;
            }
        }
        return bean;
    }

    /**
     * 复制字段值从旧实例到新实例
     */
    private void copyFieldValues(Object source, Object target) {
        Class<?> sourceClass = source.getClass();
        Class<?> targetClass = target.getClass();

        while (sourceClass != null && targetClass != null) {
            for (Field sourceField : sourceClass.getDeclaredFields()) {
                try {
                    Field targetField = targetClass.getDeclaredField(sourceField.getName());
                    if (targetField.getType().isAssignableFrom(sourceField.getType())) {
                        sourceField.setAccessible(true);
                        targetField.setAccessible(true);
                        targetField.set(target, sourceField.get(source));
                    }
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    // 忽略不存在的字段或访问异常
                }
            }
            sourceClass = sourceClass.getSuperclass();
            targetClass = targetClass.getSuperclass();
        }
    }

}
